function ExploreEndless(param) {
try{
	var that = this;
	
	this.j_items_container = null;
	this.j_loading_status = null;
	this.j_load_msg = null;
	this.j_explore_all = null;
	this.j_explore_video = null;
	this.j_explore_book = null;
	
	var retrieve_url = "";              // mandatory
	var retrieve_params = {};
	var offset = 5;              // by default
	var order_by = "DESC";       // by default
	var no_results_msg = "NO RESULTS FOUND";       // by default
	var no_more_results_msg = "NO MORE RESULTS";       // by default
	var error_msg = "This stream is unavailable at this time. Please try again soon.";    // by default
	
	var retrieving = false;
	var cur_showing_no = 0;
	var init_total = 0;
	var has_init_total = false;
	
	var category = "";
	
	var col1_height = 0;
	var col2_height = 0;
	var col3_height = 0;
	var col4_height = 0;
	
	var col1_left = 0;
	var col2_left = 248;
	var col3_left = 496;
	var col4_left = 744;
	
	var col_left_array = new Array(col1_left, col2_left, col3_left, col4_left);
	var col_height_array = new Array(col1_height, col2_height, col3_height, col4_height);
	
	var vertical_gap = 16;
	
	function __construct(p) {
	try{
		for(pkey in p) {
			if(pkey[0] != "_") {
				that[pkey] = p[pkey];
			}
		}
	
		if(p._retrieve_url) {
			retrieve_url = p._retrieve_url;
		}
		if(p._offset) {
			offset = p._offset;
		}
		if(p._order_by) {
			order_by = p._order_by;
		}
		if(p._no_results_msg) {
			no_results_msg = p._no_results_msg;
		}
		if(p._error_msg) {
			error_msg = p._error_msg;
		}
		
		jq(window).scroll(function () {
			if (jq(window).scrollTop() >= jq(document).height() - jq(window).height() - 50) {
   				// Add something at the end of the page
   				if(cur_showing_no > 0 && cur_showing_no < init_total) {
   					retrieve();
   				}
			}
		});
		
		that.j_explore_all.click(exploreAllClick);
		that.j_explore_video.click(exploreVideoClick);
		that.j_explore_book.click(exploreBookClick);
		
	}catch(err) {
		alert(err);
	}
	}
	
	function retrieve() {
	try{
		if(!retrieving) {
			retrieving = true;
			that.j_loading_status.show();
	
			retrieve_params["category"] = category;
			retrieve_params["has_init_total"] = has_init_total;
			retrieve_params["init_total"] = init_total;
			retrieve_params["cur_showing_no"] = cur_showing_no;
			retrieve_params["offset"] = offset;
			retrieve_params["order_by"] = order_by;
			
			jq.get(retrieve_url, retrieve_params, retrieveSuccess)
			.error(function() {
		    	// alert("Oops! An error occurred while processing your request.");
				that.j_load_msg.text(error_msg);
				that.j_load_msg.show();
		    })
		    .complete(function() {
		   		// complete
				that.j_loading_status.hide();
				retrieving = false;
		    });

		}
	}catch(err) {
		alert(err);
	}
	}
	
	function retrieveSuccess(data) {
	try{
		if(!has_init_total) {
			init_total = data.total;
			has_init_total = true;
		}
		
		jq.each(data.items, function(index, item) {
			that.j_items_container.append(item.html);
			var cur_item = that.j_items_container.children().last();
			var cur_item_height = cur_item.outerHeight();
			var cur_offset = getPosition(cur_item_height);
			cur_item.css({ "top" : cur_offset.top, "left" : cur_offset.left });
		});

		cur_showing_no += data.items.length;

    	// calculate the height of container
    	
		var max_height = col_height_array[0];
		for(var i=0; i<col_height_array.length-1; i++) {
			if(col_height_array[i+1] > max_height) {
				max_height = col_height_array[i+1];
			}
    	}
    	that.j_items_container.css({ "height" : max_height + "px" });
		
		if(cur_showing_no == 0) {
			that.j_load_msg.text(no_results_msg);
			that.j_load_msg.show();
		}else if(cur_showing_no < init_total) {
			// do nothing
		}else if(cur_showing_no >= init_total) {
			that.j_load_msg.text(no_more_results_msg);
			that.j_load_msg.show();
		}
	}catch(err) {
		alert(err);
	}
	}
	
	function getPosition(ele_height) {
	try{
		var min_height = col_height_array[0];
		var min_height_col = 0;
		for(var i=0; i<col_height_array.length-1; i++) {
			if(col_height_array[i+1] < min_height) {
				min_height = col_height_array[i+1];
				min_height_col = i+1;
			}
    	}
    	var cur_offset = { "top" : col_height_array[min_height_col] , "left" : col_left_array[min_height_col] };
    	col_height_array[min_height_col] = col_height_array[min_height_col] + ele_height + vertical_gap;
    	
		return cur_offset;
	}catch(err) {
		alert(err);
	}	
	}
	

	function beforeCategorySearch() {
		that.j_items_container.empty();
		
		cur_showing_no = 0;
		init_total = 0;
		has_init_total = false;

		col1_height = 0;
		col2_height = 0;
		col3_height = 0;
		col4_height = 0;
		col_left_array = new Array(col1_left, col2_left, col3_left, col4_left);
		col_height_array = new Array(col1_height, col2_height, col3_height, col4_height);
    	that.j_items_container.css({ "height" : "0px" });
	}
	
	function exploreAllClick(e) {
		try{
	    	e.preventDefault();
	    	beforeCategorySearch();
	    	category = "";
	    	hightlightSelected();
	    	retrieve();
		}catch(err) {
			alert(err);
		}
	}
	
	function exploreVideoClick(e) {
		try{
	    	e.preventDefault();
	    	beforeCategorySearch();
	    	category = "video";
	    	hightlightSelected();
	    	retrieve();
		}catch(err) {
			alert(err);
		}
	}	
	
	function exploreBookClick(e) {
		try{
	    	e.preventDefault();
	    	beforeCategorySearch();
	    	category = "book";
	    	hightlightSelected();
	    	retrieve();
		}catch(err) {
			alert(err);
		}
	}

	function hightlightSelected() {
		if(category === "") {
			if(!that.j_explore_all.hasClass("fwb")) {
				that.j_explore_all.addClass("fwb");
			}
			if(that.j_explore_video.hasClass("fwb")) {
				that.j_explore_video.removeClass("fwb");
			}
			if(that.j_explore_book.hasClass("fwb")) {
				that.j_explore_book.removeClass("fwb");
			}
		}
		if(category === "video") {
			if(!that.j_explore_video.hasClass("fwb")) {
				that.j_explore_video.addClass("fwb");
			}
			if(that.j_explore_all.hasClass("fwb")) {
				that.j_explore_all.removeClass("fwb");
			}
			if(that.j_explore_book.hasClass("fwb")) {
				that.j_explore_book.removeClass("fwb");
			}
		}
		if(category === "book") {
			if(!that.j_explore_book.hasClass("fwb")) {
				that.j_explore_book.addClass("fwb");
			}
			if(that.j_explore_all.hasClass("fwb")) {
				that.j_explore_all.removeClass("fwb");
			}
			if(that.j_explore_video.hasClass("fwb")) {
				that.j_explore_video.removeClass("fwb");
			}
		}
	}
	
	__construct(param);
	
	retrieve();

}catch(err) {
	alert(err);
}
}

	
